package com.pickgliss.ui.controls
{
	import com.pickgliss.events.ComponentEvent;
	import com.pickgliss.events.FrameEvent;
	import com.pickgliss.geom.InnerRectangle;
	import com.pickgliss.geom.OuterRectPos;
	import com.pickgliss.toplevel.StageReferance;
	import com.pickgliss.ui.ComponentFactory;
	import com.pickgliss.ui.core.Component;
	import com.pickgliss.ui.text.FilterFrameText;
	import com.pickgliss.utils.ClassUtils;
	import com.pickgliss.utils.DisplayUtils;
	import com.pickgliss.utils.ObjectUtils;
	
	import flash.display.DisplayObject;
	import flash.display.InteractiveObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.ui.Keyboard;

	[Event(name="response",type="com.pickgliss.events.FrameEvent")]
	public class Frame extends Component
	{
		public static const P_backgound:String = "backgound";
		public static const P_closeButton:String = "closeButton";
		public static const P_closeButton_Enable:String = "P_closeButton_Enable";
		public static const P_closeInnerRect:String = "closeInnerRect";
		public static const P_containerX:String = "containerX";
		public static const P_containerY:String = "containerY";
		public static const P_disposeChildren:String = "disposeChildren";
		public static const P_moveEnable:String = "moveEnable";
		public static const P_moveInnerRect:String = "moveInnerRect";
		public static const P_title:String = "title";
		public static const P_titleText:String = "titleText";
		
		public static var closeSoundFunc:Function;
		public static var submitSoundFunc:Function;
		
		public var frameType:uint;
		public function Frame()
		{
			super();
			addEventListener(Event.ADDED_TO_STAGE,__onAddToStage);
			addEventListener(MouseEvent.MOUSE_DOWN,__onMouseClickSetFocus);
		}

		protected function __onMouseClickSetFocus(event:MouseEvent):void
		{
			StageReferance.stage.focus = event.target as InteractiveObject;
		}

		protected var _backStyle:String;
		protected var _backgound:DisplayObject;
		protected var _closeButton:BaseButton;
		protected var _closeButtonEnable:Boolean;
		protected var _closeInnerRect:InnerRectangle;
		protected var _closeInnerRectString:String;
		protected var _closestyle:String;
		protected var _container:Sprite;
		protected var _containerPosString:String;
		protected var _containerX:Number;
		protected var _containerY:Number;
		protected var _moveEnable:Boolean;
		protected var _moveInnerRect:InnerRectangle;
		protected var _moveInnerRectString:String = "";
		protected var _moveRect:Sprite;
		protected var _title:TextField;
		protected var _titleStyle:String;
		protected var _titleText:String = "";
		protected var _disposeChildren:Boolean = true;
		
		/**
		 * 是否有打开窗口
		 */		
		private static var _openCount:int = 0;
		public static function get hasOpenFrame():Boolean{
			return _openCount > 0;
		}
		public static function set hasOpenFrame(val:Boolean):void{
			val ? _openCount++ : _openCount--;
			_openCount < 0 ? _openCount = 0 : _openCount;
		}

		/**
		 * 
		 * @param display 添加到内容容器的显示对象
		 * 内容容器的定位通过 containerX containerY 来设置
		 * 
		 */		
		public function addToContent(display:DisplayObject):void
		{
			_container.addChild(display);
		}
		public function addToContentAt(display:DisplayObject,index:int):void
		{
			_container.addChildAt(display,index);
		}
		/**
		 * 
		 * @param stylename 背景的样式
		 * 
		 */		
		public function set backStyle(stylename:String):void
		{
			if(_backStyle == stylename) return;
			_backStyle =  stylename;
			backgound = ComponentFactory.Instance.creat(_backStyle);
		}
		
		public function get backStyle():String
		{
			return _backStyle;
		}
		/**
		 * 
		 * @param image 背景
		 * 
		 */		
		public function set backgound(image:DisplayObject):void
		{
			if(_backgound == image) return;
			ObjectUtils.disposeObject(_backgound);
			_backgound = image;
			if(_backgound is InteractiveObject)InteractiveObject(_backgound).mouseEnabled = true;
			onPropertiesChanged(P_backgound);
		}
		
		/**
		 * 
		 * 关闭按钮
		 * 
		 */		
		public function get closeButton():BaseButton
		{
			return _closeButton;
		}
		public function set closeButton(button:BaseButton):void
		{
			if(_closeButton == button) return;
			if(_closeButton)_closeButton.addEventListener(MouseEvent.CLICK,__onCloseClick);
			ObjectUtils.disposeObject(_closeButton);
			_closeButton = button;
			onPropertiesChanged(P_closeButton);
		}
		/**
		 * 
		 * @param value 设置图标的InnerRectangle
		 * 具体请看InnerRectangle
		 * 
		 */		
		public function set closeInnerRectString(value:String):void
		{
			if(_closeInnerRectString == value)return;
			_closeInnerRectString = value;
			_closeInnerRect = ClassUtils.CreatInstance(ClassUtils.INNERRECTANGLE,ComponentFactory.parasArgs(_closeInnerRectString));
			onPropertiesChanged(P_closeInnerRect);
		}
		
		public function get closeInnerRectString():String
		{
			return _closeInnerRectString;
		}
		/**
		 * 
		 * @param stylename 关闭按钮的样式
		 * 通过ComponentFactory 创建
		 */		
		public function set closestyle(stylename:String):void
		{
			if(_closestyle == stylename) return;
			_closestyle =  stylename;
			closeButton = ComponentFactory.Instance.creat(_closestyle);
		}
		public function get closestyle():String
		{
			return _closestyle;
		}
		/**
		 * 
		 * @param value 内容容器的x坐标
		 * 
		 */		
		public function set containerX(value:Number):void
		{
			if(_containerX == value) return;
			_containerX = value;
			onPropertiesChanged(P_containerX);
		}
		public function get containerX():Number
		{
			return _containerX;
		}
		/**
		 * 
		 * @param value 内容容器的y坐标
		 * 
		 */		
		public function set containerY(value:Number):void
		{
			if(_containerY == value) return;
			_containerY = value;
			onPropertiesChanged(P_containerY);
		}
		public function get containerY():Number
		{
			return _containerY;
		}
		
		protected var _titleOuterRectPosString:String;
		public static const P_titleOuterRectPos:String = "titleOuterRectPos";
		protected var _titleOuterRectPos:OuterRectPos;
		public function set titleOuterRectPosString(value:String):void
		{
			if(_titleOuterRectPosString == value)return;
			_titleOuterRectPosString = value;
			_titleOuterRectPos = ClassUtils.CreatInstance(ClassUtils.OUTTERRECPOS,ComponentFactory.parasArgs(_titleOuterRectPosString));
			onPropertiesChanged(P_titleOuterRectPos);
		}
		public function get titleOuterRectPosString():String
		{
			return _titleOuterRectPosString;
		}
		
		override public function dispose():void
		{
			var focusDisplay:DisplayObject = StageReferance.stage.focus as DisplayObject;
			if(focusDisplay && contains(focusDisplay))StageReferance.stage.focus = null;
			StageReferance.stage.removeEventListener(MouseEvent.MOUSE_UP,__onFrameMoveStop);
			StageReferance.stage.removeEventListener(MouseEvent.MOUSE_MOVE,__onMoveWindow);
			removeEventListener(KeyboardEvent.KEY_DOWN,__onKeyDown);
			removeEventListener(MouseEvent.MOUSE_DOWN,__onMouseClickSetFocus);
			removeEventListener(Event.ADDED_TO_STAGE,__onAddToStage);
			hasOpenFrame = false;
			
			if(_backgound)ObjectUtils.disposeObject(_backgound);
			_backgound = null;
			
			if(_closeButton)
			{
				_closeButton.removeEventListener(MouseEvent.CLICK,__onCloseClick);
				ObjectUtils.disposeObject(_closeButton);
			}
				
			_closeButton = null;
			if(_title)ObjectUtils.disposeObject(_title);
			_title = null;
			if(_disposeChildren)ObjectUtils.disposeAllChildren(_container);
			if(_container)ObjectUtils.disposeObject(_container);
			_container = null;
			if(_moveRect)_moveRect.removeEventListener(MouseEvent.MOUSE_DOWN,__onFrameMoveStart);
			ObjectUtils.disposeObject(_moveRect);
			_moveRect = null;
			super.dispose();
//			FrameManager.removeFrame(this);
		}
		/**
		 * 
		 * 是否清除子对象，默认值为true
		 * 
		 */		
		public function get disposeChildren():Boolean
		{
			return _disposeChildren;
		}
		
		public function set disposeChildren(value:Boolean):void
		{
			if(_disposeChildren == value)return;
			_disposeChildren = value;
			onPropertiesChanged(P_disposeChildren);
		}
		/**
		 * 
		 * @param value 能否移动窗体
		 * 
		 */		
		public function set moveEnable(value:Boolean):void
		{
			if(_moveEnable == value)return;
			_moveEnable = value;
			onPropertiesChanged(P_moveEnable);
		}
		/**
		 * 
		 * @param value 设置拖动的鼠标响应区域的InnerRectangle
		 * 具体请看InnerRectangle
		 * 
		 */		
		public function set moveInnerRectString(value:String):void
		{
			if(_moveInnerRectString == value)return;
			_moveInnerRectString = value;
			_moveInnerRect = ClassUtils.CreatInstance(ClassUtils.INNERRECTANGLE,ComponentFactory.parasArgs(_moveInnerRectString));
			onPropertiesChanged(P_moveInnerRect);
		}
		public function get moveInnerRectString():String
		{
			return _moveInnerRectString;
		}
		/**
		 * 
		 * @param text 标题文本框
		 * 
		 */		
		public function set title(text:TextField):void
		{
			if(_title == text) return;
			_title = text;
			onPropertiesChanged(P_title);
		}
		/**
		 * 
		 * @param stylename 标题样式
		 * 
		 */		
		public function set titleStyle(stylename:String):void
		{
			if(_titleStyle ==stylename) return;
			_titleStyle = stylename;
			title = ComponentFactory.Instance.creat(_titleStyle);
		}
		public function get titleStyle():String
		{
			return _titleStyle;
		}
		/**
		 * 
		 * @param value 标题文本
		 * 
		 */		
		public function set titleText(value:String):void
		{
			if(_titleText ==value) return;
			_titleText = value;
			onPropertiesChanged(P_titleText);
		}
		public function get titleText():String
		{
			return _titleText;
		}
		
		
		protected function __onAddToStage(event:Event):void
		{
			hasOpenFrame = true;
			if(!checkInputTxt())
				stage.focus = this;
		}
		
		private function checkInputTxt():Boolean
		{
			if(!StageReferance.stage)return false;
			var obj:FilterFrameText = StageReferance.stage.focus as FilterFrameText;
			if(obj && obj.type == "input")
				return true;
			else 
				return false;
		}
		
		protected function __onCloseClick(event:MouseEvent):void
		{
			closeSoundFunc();
			onResponse(FrameEvent.CLOSE_CLICK);
		}
		
		protected function __onKeyDown(event:KeyboardEvent):void
		{
			var focusTarget:DisplayObject = StageReferance.stage.focus as DisplayObject;
			if(DisplayUtils.isTargetOrContain(focusTarget,this))
			{
				if(event.keyCode == Keyboard.ENTER && enterEnable)
				{
					submitSoundFunc();
					if(focusTarget is TextField && TextField(focusTarget).type == TextFieldType.INPUT)return;
					onResponse(FrameEvent.ENTER_CLICK);
					event.stopImmediatePropagation();
				}else if(event.keyCode == Keyboard.ESCAPE && escEnable)
				{
					closeSoundFunc();
					onResponse(FrameEvent.ESC_CLICK);
					event.stopImmediatePropagation();
				}
			}
		}
		
		protected var _escEnable:Boolean;
		public static const P_escEnable:String = "escEnable";
		public function set escEnable(value:Boolean):void
		{
			if(_escEnable == value)return;
			_escEnable = value;
			onPropertiesChanged(P_escEnable);
		}
		
		public function get escEnable():Boolean
		{
			return _escEnable;
		}
		
		protected var _enterEnable:Boolean;
		public static const P_enterEnable:String = "enterEnable";
		public function set enterEnable(value:Boolean):void
		{
			if(_enterEnable == value)return;
			_enterEnable = value;
			onPropertiesChanged(P_enterEnable);
		}
		
		public function get enterEnable():Boolean
		{
			return _enterEnable;
		}
		
		protected function onResponse(type:int):void
		{
			dispatchEvent(new FrameEvent(type));
		}
		
		protected function __onFrameMoveStart(event:MouseEvent):void
		{
			StageReferance.stage.addEventListener(MouseEvent.MOUSE_MOVE,__onMoveWindow);
			StageReferance.stage.addEventListener(MouseEvent.MOUSE_UP,__onFrameMoveStop);
			startDrag();
		}
		
		protected function __onFrameMoveStop(event:MouseEvent):void
		{
			dispatchEvent(new ComponentEvent(ComponentEvent.FRAME_MOVE_COMPLETE));
			StageReferance.stage.removeEventListener(MouseEvent.MOUSE_UP,__onFrameMoveStop);
			StageReferance.stage.removeEventListener(MouseEvent.MOUSE_MOVE,__onMoveWindow);
			stopDrag();
		}
		
		override protected function addChildren():void
		{
			if(_backgound)addChild(_backgound);
			addChild(_container);
			if(_title)addChild(_title);
			addChild(_moveRect);
			if(_closeButton)addChild(_closeButton);
		}
		
		override protected function init():void
		{
			_container = new Sprite();
			_moveRect = new Sprite();
			super.init();
		}
		
		
		override protected function onProppertiesUpdate():void
		{
			super.onProppertiesUpdate();
			
			if((_changedPropeties[Component.P_height] || _changedPropeties[Component.P_width] ||  _changedPropeties[P_backgound]) && _backgound != null)
			{
				_backgound.width = _width;
				_backgound.height = _height;
				updateClosePos();
			}
			
			if(_changedPropeties[Component.P_height] || _changedPropeties[Component.P_width] || _changedPropeties[P_moveInnerRect])
			{
				updateMoveRect();
			}
			
			if(_changedPropeties[P_closeButton])
			{
				_closeButton.addEventListener(MouseEvent.CLICK,__onCloseClick);
			}
			
			if(_changedPropeties[P_closeButton] || _changedPropeties[P_closeInnerRect])
			{
				updateClosePos();
			}
			
			if(_changedPropeties[P_containerX] || _changedPropeties[P_containerY])
			{
				updateContainerPos();
			}
			
			if(_changedPropeties[P_titleOuterRectPos] || _changedPropeties[P_titleText] ||_changedPropeties[Component.P_height] || _changedPropeties[Component.P_width])
			{
				if(_title != null)_title.text = _titleText;
				updateTitlePos();
			}
			
			if(_changedPropeties[P_moveEnable])
			{
				if(_moveEnable)
				{
					_moveRect.addEventListener(MouseEvent.MOUSE_DOWN,__onFrameMoveStart);
				}else
				{
					_moveRect.removeEventListener(MouseEvent.MOUSE_DOWN,__onFrameMoveStart);
				}
			}
			
			if(_changedPropeties[P_closeButton_Enable])
			{
				if(_closeButton) _closeButton.enable = _closeButtonEnable;
			}
			
			if(_escEnable || _enterEnable)
			{
				addEventListener(KeyboardEvent.KEY_DOWN,__onKeyDown);
			}else
			{
				removeEventListener(KeyboardEvent.KEY_DOWN,__onKeyDown);
			}
		}
		
		
		protected function updateClosePos():void
		{
			if(_closeButton && _closeInnerRect)
			{
				DisplayUtils.layoutDisplayWithInnerRect(_closeButton,_closeInnerRect,_width,_height);
			}
		}
		
		protected function updateContainerPos():void
		{
			_container.x = _containerX;
			_container.y = _containerY;
		}
		
		protected function updateMoveRect():void
		{
			if(_moveInnerRect == null)return;
			var resultRect:Rectangle = _moveInnerRect.getInnerRect(_width,_height);
			_moveRect.graphics.clear();
			_moveRect.graphics.beginFill(0x000000,0);
			_moveRect.graphics.drawRect(resultRect.x,resultRect.y,resultRect.width,resultRect.height);
			_moveRect.graphics.endFill();
		}
		
		protected function updateTitlePos():void
		{
			if(_title == null) return;
			if(_titleOuterRectPos == null)return;
			var posRect:Point = _titleOuterRectPos.getPos(_title.width,_title.height,_width,_height);
			_title.x = posRect.x;
			_title.y = posRect.y;
		}
		
		protected function __onMoveWindow(event:MouseEvent):void
		{
			if(DisplayUtils.isInTheStage(new Point(event.localX,event.localY),this))
			{
//				event.updateAfterEvent();
			}else
			{
				__onFrameMoveStop(null);
			}
		}

		public function get closeButtonEnable():Boolean
		{
			return _closeButtonEnable;
		}

		public function set closeButtonEnable(value:Boolean):void
		{
			_closeButtonEnable = value;
			onPropertiesChanged(P_closeButton_Enable);
		}

		
	}
}